/* Speicherverwaltung (Codename "Svante August Arrhenius") */
/* ************************************************* *
 * Diese Datei soll von ihnen vervollst�ndigt werden *
 * ************************************************* */

#include "memory_management.h"
#include "lib.h"
#include "serial.h"



/** initialisiert die Speicherverwaltung

 */
int kmem_init() {
	int i;
  
	/* für Skyeye auskomentiert, damit der Speicher schneller lädt
	for(i=0; i<MEMORYLENGTH; i++){
	  memory[i] = 0;
	}
	*/
	
	for(i=0; i<MEMORYLENGTH/1024; i++){
	  mapping[i] = 0;
	}
	
	
	printf("Initialisierung des Speichers abgeschlossen, Startadresse: %x\n", memory); 
	return 1;
}


/** belegt einen Speicherbereich
 *   length        die Größe in bytes, der typ size_t steht für einen
 *                 Ganzzahlenwert und kann wie long verwendet werden
 */
void *kmalloc(unsigned long size) {
	int blocksize;//
	blocksize = size/1024;
	if(size % 1024 != 0){
	    blocksize++;
	}// Speicher wird auf das nächste volle kb aufgerundet
	//printf("Gesuchte Blockgröße: %d\n", blocksize);
	int i;
	int ct = 0;
	//write("Alloziiiere Speicher\n");
	for(i=0; i<MEMORYLENGTH/1024; i++){
	  if(ct >= blocksize){ //passender Speicherbereich gefunden
		  //printf("Alloziiiere Speicher an Adresse: %x\n",&memory[(i-ct)*1024]);
		  mapping[i-ct]=blocksize;
		  return &memory[(i-ct)*1024];
	  }
	  if(mapping[i]){ // gefundener Speicherbereich war zu klein ct zurücksetzen
		ct = 0;		
		i += mapping[i--];
		//i--;
	  }
	  else{
	    ct++;
	  }
	}

	return 0;
}

/** gibt den zuvor belegten Speicherbereich wieder frei. Die Größe des
 *  freizugebenen Stückes soll von der Speicherverwaltung selbst bestimmt
 *  werden.
 */
void kfree( void *mem, unsigned long size ) {
	//printf("Gebe Speicher der Adresse: %x, frei\n", mem); 
	mapping[((long int)mem-(long int)memory)/1024]=0;
}
